home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
kms20src.lha
/
KMSAUX
/
axaux-handler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-25
|
43KB
|
996 lines
/****************************************************************************
lc -b0 -v -csu -r -j73 AXAux-Handler.c
blink AXAux-Handler.o TO AXsh:bin/AXAux-Handler LIBRARY lib:lc.lib lib:amiga.lib
copy AXAux-Handler.c AXsh:usr/src/
quit
*
* AXAUX:serial.device/0/raw[con]/exclusive[shared]/7wire[noflow]/speed<speed>
*
* Aux-Handler Ver. 1.1 20-Jul-1991
* Ver. 1.15 9-Jan-1992
* Ver. 1.20 14-Apr-1992
* Ver. 1.25 11-Oct-1992
* Ver. 1.26 30-Jan-1993
*
* Pasi Ojala
* Kostulantie 67/50
* 39230 Osara
*
* Aux Driver V1.0 (c)CopyRight 1987, Steve Drew.
*
* Steve Drew
* 52-Castledale Cres. N.E.
* Calgary, Ab. Canada.
***************************************************************************/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/memory.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <devices/serial.h>
#include <devices/timer.h>
#include <devices/console.h>
#include <libraries/filehandler.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
/*
#include <proto/exec.h>
#include <proto/dos.h>
*/
char *vers="\0$VER: AXAUX-Handler 1.26 (30-Jan-93)\n";
#undef BADDR
#define BADDR(x) ((APTR)((long)x << 2))
/* these are defined in dosextens..
#define ACTION_WAIT_CHAR 20
#define ACTION_WRITE 'W'
#define ACTION_READ 'R'
#define ACTION_FINDINPUT 1005L
#define ACTION_FINDOUTPUT 1006L
#define ACTION_END 1007L
#define ACTION_SCREEN_MODE 994L */
#define ACTION_QUERY 64 /* our own action */
#define MODE_CONSOLE 0 /* normal buffered console mode */
#define MODE_RAW 1 /* raw mode, no line editing nor echo */
#define MODE_NOCRLF 2 /* CR not added to LF, all codes will be sent (0)*/
#define DOS_FALSE 0L
#define DOS_TRUE -1L
#define AUX_ECHO 1 /* echo characters */
#define AUX_CRLF 2 /* append LF to CR and vice versa (output) */
#define AUX_TYPEAHEAD_FULL 32 /* aux-buffer is full, CMD_READ NOT active */
#define AUXBUFSIZE 8192
#define MAXLINESIZE AUXBUFSIZE-2 /* save two for \n'\0' */
#define OUTBUFSIZE 1024
#define DEVICENAMELEN 32
#define MYPORT_SIG (1L<<myport->mp_SigBit) /* signal bit for requests */
#define READSER_SIG (1L<<ReadSER->IOSer.io_Message.mn_ReplyPort->mp_SigBit)
#define TIMER_SIG (1L<<Timer_Port->mp_SigBit)
/* Prototypes */
void returnpkt(struct DosPacket*,struct Process*,ULONG,ULONG); /* sends back the packet */
struct DosPacket *taskwait();
void close_timer(void);
void close_ser(void);
int open_stuff(void);
void puts_ser(UBYTE *buf,int len);
void write_ser(UBYTE *,int);
int buf_ser(UBYTE *frombuf,int size);
int query_ser(void);
void get_ser(UBYTE *destbuf,int size);
void set_read(void);
void chk_file(char *);
/* Globals */
struct IOExtSer *ReadSER;
struct IOExtSer *WriteSER;
struct IOExtSer *QuerySER;
struct timerequest *Timer;
struct MsgPort *Timer_Port;
struct Task *reader;
/*
VOID *SysBase;
*/
int aux_stat,aux_avail,in_len;
UBYTE in_c,checkcd,serflags,breakallowed,Mode;
long unitnum,SerialStatus,SerialSpeed;
char device[DEVICENAMELEN],
outbuf[OUTBUFSIZE+1],
*auxbuf; /* Our type ahead buffer */
void __geta4 handler() /* this is kinda main() */
{
struct Process *myproc; /* my process */
struct DosPacket *mypkt,*rdpkt=NULL,*waitpkt=NULL;
/* pointers to the dos packets */
struct DeviceNode *mynode; /* our device node (parmpkt Arg3) */
struct FileHandle *fh; /* a pointer to our file handle */
struct MsgPort *myport;
BOOL run=TRUE; /* handler main loop flag */
UBYTE *ptr; /* ptr for name translation */
char *s; /* ptr to name for open */
int i,tmp,aux_open=0; /* aux open count */
long signals; /* signals that occurred */
char name[200]; /* filename passed to */
/* Initializing the handler */
/*
SysBase=*(void **)4;
*/
myproc = (struct Process *)FindTask(0L);
mypkt = taskwait(myproc); /* Wait for the startup message */
/* We don't need the name or extra info passed in Arg1/2 */
mynode = (struct DeviceNode *)BADDR(mypkt->dp_Arg3);
mynode->dn_Task = &myproc->pr_MsgPort;
myport = &myproc->pr_MsgPort;
returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
auxbuf=0L;
SerialStatus=breakallowed=in_len=aux_avail=0;
aux_stat=AUX_CRLF;
Mode=MODE_RAW;
reader = (struct Task *)NULL;
checkcd=0;
/* done initial stuff, now for some work */
while(run)
{
if(aux_open) /* then wait for read char or new action */
{
signals=Wait(MYPORT_SIG | READSER_SIG | TIMER_SIG);
if((signals & TIMER_SIG) && CheckIO((struct IORequest *)Timer))
{
WaitIO((struct IORequest *)Timer);
if(waitpkt)
{
(void)query_ser();
if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
{
Signal(waitpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
/* EOF can be read :-) */
}
else
if(in_len) /* TODO: handle chars in serial buffer */
{
returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
}
else
{
returnpkt(waitpkt,myproc,DOS_FALSE,waitpkt->dp_Res2);
}
waitpkt=NULL;
}
}
if((signals & READSER_SIG) && CheckIO((struct IORequest *)ReadSER))
{
WaitIO((struct IORequest *)ReadSER); /* fine, got a char */
if(buf_ser(&in_c,1))
{
tmp=query_ser();
if(tmp && AUXBUFSIZE-in_len-2>10)
{
if(tmp>AUXBUFSIZE-in_len-9)
tmp=AUXBUFSIZE-in_len-10; /* hysteresis */
get_ser(outbuf,tmp);
buf_ser(outbuf,tmp);
}
set_read(); /* because buffer is not full, start another read */
}
if(waitpkt)
{
AbortIO((struct IORequest *)Timer);
WaitIO((struct IORequest *)Timer);
Wait(TIMER_SIG);
if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
{
Signal(waitpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
/* EOF can be read :-) */
}
else
{
returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
}
waitpkt=NULL;
}
if(rdpkt)
{
if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
{
Signal(rdpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
returnpkt(rdpkt,myproc,DOS_FALSE,rdpkt->dp_Res2);
/* return EOF */
rdpkt=NULL;
}
else
{
if(Mode==MODE_RAW)
{
if(in_len)
{
if(in_len<=rdpkt->dp_Arg3)
{
movmem(auxbuf,(UBYTE *)rdpkt->dp_Arg2,in_len);
i=in_len;
aux_avail=in_len=0;
}
else
{
i=rdpkt->dp_Arg3;
movmem(auxbuf,(UBYTE *)rdpkt->dp_Arg2,i);
in_len-=i;
movmem(auxbuf+i,auxbuf,in_len);
aux_avail=tmp=0;
while(tmp<in_len)
if(auxbuf[tmp++]=='\n')
aux_avail++;
}
if((aux_stat & AUX_TYPEAHEAD_FULL) && in_len<MAXLINESIZE-1)
{
aux_stat &= ~AUX_TYPEAHEAD_FULL;
set_read(); /* start waiting for reads again */
}
returnpkt(rdpkt,myproc,(long)i,rdpkt->dp_Res2);
rdpkt=NULL;
}
}
else
{
if(aux_avail)
{
aux_avail--;
i=0;
ptr=(UBYTE *)rdpkt->dp_Arg2;
while(i<rdpkt->dp_Arg3 && i<in_len)
{
if((ptr[i]=auxbuf[i])=='\n')
{
i++;
break;
}
i++;
}
in_len-=i;
movmem(auxbuf+i,auxbuf,in_len);
if(ptr[i-1]!='\n')
aux_avail++;
if((aux_stat & AUX_TYPEAHEAD_FULL) && in_len<MAXLINESIZE-1)
{
aux_stat &= ~AUX_TYPEAHEAD_FULL;
set_read(); /* start waiting for reads again */
}
returnpkt(rdpkt,myproc,(long)i,rdpkt->dp_Res2);
rdpkt=NULL;
}
}
}
}
}
if(signals & MYPORT_SIG)
{
mypkt=taskwait(myproc); /* somebody wanting to talk to us ? */
}
else
continue; /* no new dospackets - back to the beginning */
}
else
mypkt=taskwait(myproc); /* otherwise we just sit here and wait for someone to need us */
switch(mypkt->dp_Type) /* find what action to perform */
{
case ACTION_FINDINPUT:
/* Have I already got someone reading and it is not 'reopen'.. */
if(reader && (*((UBYTE *)BADDR(mypkt->dp_Arg3)+1)!='*'))
{
returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
break;
}
breakallowed=0; /* fall through */
case ACTION_FINDOUTPUT:
/* Multiple writers are allowed. */
/* get file name and Upper case it */
ptr=(UBYTE *)BADDR(mypkt->dp_Arg3);
movmem(ptr+1,name,*ptr);
name[*ptr]='\0';
for(s=name;*s;s++)
*s=tolower(*s);
s=name;
if(strcmp(name,"*"))
{
while(*s!=':' && *s)
s++; /* skip the handler name */
if(*s!=':') /* weird, no handler name */
{
returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
break;
}
else
s++;
if(!strncmp(s,"break",5)) /* trying to send a break to the reader ? */
{
if(reader)
{
Signal(reader,SIGBREAKF_CTRL_C);
Signal(reader,SIGBREAKF_CTRL_D);
}
returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
break;
}
if(!aux_open) /* first time here we open the devices */
{
chk_file(s); /* check parameters */
if(!(aux_open=open_stuff()))
{
returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
break;
}
}
else
aux_open++;
}
else
{ /* the same channel */
if(!aux_open)
{
returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
break;
}
aux_open++;
}
fh = (struct FileHandle *)BADDR(mypkt->dp_Arg1);
fh->fh_Arg1=DOS_TRUE;
fh->fh_Port=(struct MsgPort *)DOS_TRUE;
if(!reader && (mypkt->dp_Type==ACTION_FINDINPUT))
{ struct MsgPort *port;
port=mypkt->dp_Port;
reader=port->mp_SigTask;
fh->fh_Arg1=(long)port->mp_SigTask;
}
returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
break;
case ACTION_READ:
rdpkt=mypkt;
(void)query_ser();
if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
{
Signal(rdpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
returnpkt(rdpkt,myproc,0,rdpkt->dp_Res2); /* return EOF */
rdpkt=NULL;
}
else
{
if(Mode==MODE_RAW)
{
if(in_len)
{
if(in_len<=rdpkt->dp_Arg3)
{
movmem(auxbuf,(UBYTE *)rdpkt->dp_Arg2,in_len);
i=in_len;
aux_avail=in_len=0;
}
else
{
i=rdpkt->dp_Arg3;
movmem(auxbuf,(UBYTE *)rdpkt->dp_Arg2,i);
in_len-=i;
movmem(auxbuf+i,auxbuf,in_len);
aux_avail=tmp=0;
while(tmp<in_len)
if(auxbuf[tmp++]=='\n')
aux_avail++;
}
if((aux_stat & AUX_TYPEAHEAD_FULL) && in_len<MAXLINESIZE-1)
{
aux_stat &= ~AUX_TYPEAHEAD_FULL;
set_read(); /* start waiting for reads again */
}
returnpkt(rdpkt,myproc,(long)i,rdpkt->dp_Res2);
rdpkt=NULL;
}
}
else
{
if(aux_avail)
{
aux_avail--;
i=0;
ptr=(UBYTE *)rdpkt->dp_Arg2;
while(i<rdpkt->dp_Arg3 && i<in_len)
{
if((ptr[i]=auxbuf[i])=='\n')
{
i++;
break;
}
i++;
}
in_len-=i;
movmem(auxbuf+i,auxbuf,in_len);
if(ptr[i]!='\n')
aux_avail++;
if((aux_stat & AUX_TYPEAHEAD_FULL) && in_len<MAXLINESIZE-1)
{
aux_stat &= ~AUX_TYPEAHEAD_FULL;
set_read(); /* start waiting for reads again */
}
returnpkt(rdpkt,myproc,(long)i,rdpkt->dp_Res2);
rdpkt=NULL;
break;
}
}
}
break;
case ACTION_WRITE:
write_ser((char *)mypkt->dp_Arg2,(int)mypkt->dp_Arg3);
/* tell 'em we wrote them all */
returnpkt(mypkt,myproc,mypkt->dp_Arg3,mypkt->dp_Res2);
break;
case ACTION_WAIT_CHAR: /* just queue up to wait for data */
waitpkt=mypkt;
(void)query_ser();
if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
{
Signal(waitpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
/* EOF can be read :-) */
waitpkt=NULL;
break;
}
if(in_len) /* if we have something, reply immediately */
{
returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
waitpkt=NULL;
break;
}
if(!waitpkt->dp_Arg1) /* if there is no wait, reply immediately */
{
returnpkt(waitpkt,myproc,DOS_FALSE,waitpkt->dp_Res2);
waitpkt=NULL;
break;
}
Timer->tr_time.tv_secs =0L;
Timer->tr_time.tv_micro=waitpkt->dp_Arg1;
SendIO((struct IORequest *)Timer);
break;
case ACTION_SCREEN_MODE:
breakallowed=TRUE; /* Break (^c or ^d) is allowed only after setmode */
aux_stat |= AUX_ECHO;
Mode=MODE_CONSOLE;
if(mypkt->dp_Arg1==-1) /* -1 means 'normal' Raw mode */
{
Mode=MODE_RAW;
aux_stat |= AUX_CRLF;
aux_stat &= ~AUX_ECHO;
}
else
{
if(mypkt->dp_Arg1 & MODE_RAW) /* raw means RAW and NOECHO */
{
aux_stat &= ~AUX_ECHO;
Mode=MODE_RAW;
}
if(mypkt->dp_Arg1 & MODE_NOCRLF) /* NOCRLF possible in console mode too */
{
aux_stat &= ~AUX_CRLF;
}
else
{
aux_stat |= AUX_CRLF;
}
}
returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
break;
case ACTION_QUERY:
(void)query_ser();
returnpkt(mypkt,myproc,DOS_TRUE,SerialStatus);
break;
case ACTION_END:
if(--aux_open==0)
{
run=FALSE;
close_timer();
if(!(aux_stat & AUX_TYPEAHEAD_FULL))
{ AbortIO((struct IORequest *)ReadSER);
WaitIO((struct IORequest *)ReadSER);
}
close_ser();
reader=(struct Task *)NULL;
}
if(mypkt->dp_Arg1==(long)reader)
reader=(struct Task *)NULL;
returnpkt(mypkt,myproc,DOS_TRUE,mypkt->dp_Res2);
break;
case ACTION_DISK_INFO:
default:
returnpkt(mypkt,myproc,DOS_FALSE,ERROR_ACTION_NOT_KNOWN);
break;
}
}
mynode->dn_Task=FALSE;
}
/* Start an asynchronous Read request */
void set_read()
{
ReadSER->IOSer.io_Command=CMD_READ;
ReadSER->IOSer.io_Length =1L;
ReadSER->IOSer.io_Data =(APTR)&in_c;
SendIO((struct IORequest *)ReadSER);
}
int query_ser() /* we use a dedicated IORequest */
{
QuerySER->IOSer.io_Command=SDCMD_QUERY;
DoIO((struct IORequest *)QuerySER);
SerialStatus=QuerySER->io_Status;
return (int)QuerySER->IOSer.io_Actual;
}
void get_ser(UBYTE *destbuf,int size)
{
ReadSER->IOSer.io_Command=CMD_READ;
ReadSER->IOSer.io_Data =(APTR)destbuf;
ReadSER->IOSer.io_Length =size;
DoIO((struct IORequest *)ReadSER);
}
int buf_ser(UBYTE *s,int num)
{ UBYTE c;
int i;
if(Mode==MODE_RAW)
{
/* Copy the characters */
movmem(s,auxbuf+in_len,num);
in_len+=num;
/* Check if any breaks or LF's were sent */
if(reader && breakallowed)
{
for(i=0;i<num;i++)
{
c=s[i];
if(c==0x03)
{ /* ^C typed so immediately send the signal (if it is allowed) */
Signal(reader,SIGBREAKF_CTRL_C);
break;
}
else
if(c==0x04)
{ /* ^D typed so immediately send the signal (if it is allowed) */
Signal(reader,SIGBREAKF_CTRL_D);
break;
}
else
if(c==0x0a)
aux_avail++; /* always done when CR received */
}
}
}
else
{
for(i=0;i<num;i++)
{
c=s[i];
switch(c)
{
case 0x03:
c=0;
if(reader && breakallowed)
Signal(reader,SIGBREAKF_CTRL_C);
break;
case 4:
c=0;
if(reader && breakallowed)
Signal(reader,SIGBREAKF_CTRL_D);
break;
case 28: /* ^\ so wipe out line and force EOF */
in_len=c=0;
++aux_avail;
break;
case 13: /* CR convert to LF if CRLF turned on */
if(aux_stat & AUX_CRLF)
c=0x0a;
break;
case 10: /* ignore these */
if(aux_stat & AUX_CRLF)
c=0;
break;
case 8: /* BS */
case 127: /* DEL */
if(in_len && auxbuf[in_len-1]!=0x0a)
{
--in_len;
write_ser("\010 \010",3);
}
c=0;
break;
case 24: /* ^X */
case 21: /* ^U */
while(in_len && auxbuf[in_len-1]!=0x0a)
{
--in_len;
write_ser("\010 \010",3);
}
c=0;
break;
case 27: /* <ESC> */
c=0;
default:
break;
}
if(c)
auxbuf[in_len++]=c;
if(aux_stat & AUX_ECHO)
{
if((aux_stat & AUX_CRLF) && c==0x0a)
puts_ser("\r",1);
puts_ser(&c,1);
}
if(c==0x0a)
aux_avail++; /* always done when CR received */
}
}
if(in_len>=MAXLINESIZE)
{
aux_stat|=AUX_TYPEAHEAD_FULL;
if(!aux_avail && (Mode==MODE_CONSOLE))
{
aux_avail++;
auxbuf[in_len++]=0x0a;
}
return 0; /* buffer is full */
}
return -1;
}
/* Write 'em out one by one converting to CR LF if enabled. */
void write_ser(UBYTE *buf,int len)
{ static UBYTE last=0;
int i,count=0;
UBYTE c;
if((aux_stat & AUX_CRLF) || (Mode!=MODE_RAW))
{
for(i=0;i<len;i++)
{
c=buf[i];
if(aux_stat & AUX_CRLF)
{
if(c==0x9b)
{
last=0x9b;
continue;
}
if(last==0x0a && c==0x0d) continue; /* we already sent CR */
if(last==0x9b)
{
outbuf[count++]='\033'; /* <csi> is converted to ANSI-format */
outbuf[count++]='[';
}
}
outbuf[count++]=last=c; /* if we didn't have CR after LF, we add it */
if(aux_stat & AUX_CRLF)
{
if(last==0x0a)
outbuf[count++]=0x0d;
}
if(count+4>OUTBUFSIZE) /* 3 bytes may be added in one pass */
{
puts_ser(outbuf,count);
count=0;
}
}
if(count) /* something still to send */
{
puts_ser(outbuf,count);
}
}
else
{
puts_ser(buf,len); /* in raw and nocrlf -mode just send the buffer */
last=buf[len-1];
}
}
/* write whole buffer */
void puts_ser(UBYTE *buf,int len)
{
WriteSER->IOSer.io_Length=len;
WriteSER->IOSer.io_Data=(APTR)buf;
DoIO((struct IORequest *)WriteSER);
}
int open_stuff()
{
if(!(auxbuf=(char *)AllocMem(AUXBUFSIZE,MEMF_CLEAR)))
return 0;
ReadSER =(struct IOExtSer *)AllocMem(sizeof(*ReadSER),MEMF_PUBLIC|MEMF_CLEAR);
WriteSER=(struct IOExtSer *)AllocMem(sizeof(*ReadSER),MEMF_PUBLIC|MEMF_CLEAR);
QuerySER=(struct IOExtSer *)AllocMem(sizeof(*ReadSER),MEMF_PUBLIC|MEMF_CLEAR);
if(!ReadSER || !WriteSER || !QuerySER)
{
goto endser;
}
ReadSER->IOSer.io_Message.mn_ReplyPort=(struct MsgPort *)CreatePort(0,0);
ReadSER->io_SerFlags=serflags; /* Must be defined here!! */
if(OpenDevice(device,unitnum,(struct IORequest *)ReadSER,NULL))
{
ReadSER->IOSer.io_Device=NULL;
goto endser;
}
ReadSER->IOSer.io_Command = SDCMD_SETPARAMS;
ReadSER->io_ExtFlags = 0L;
ReadSER->io_SerFlags = serflags;
/* normally CTS/RTS handshake - 8-bit protocol with no parity (RAD_BOOGIE) */
/* if speed is set in the filename part */
if(SerialSpeed!=-1)
{
ReadSER->io_Baud=SerialSpeed;
}
DoIO((struct IORequest *)ReadSER); /* if it didn't work, let the user worry :-) */
/* Make copies of the structs */
movmem((UBYTE *)ReadSER,(UBYTE *)WriteSER,sizeof(struct IOExtSer));
WriteSER->IOSer.io_Command=CMD_WRITE;
WriteSER->IOSer.io_Message.mn_ReplyPort=NULL;
movmem((UBYTE *)ReadSER,(UBYTE *)QuerySER,sizeof(struct IOExtSer));
QuerySER->IOSer.io_Command=SDCMD_QUERY;
QuerySER->IOSer.io_Message.mn_ReplyPort=NULL;
if(!(WriteSER->IOSer.io_Message.mn_ReplyPort=(struct MsgPort *)CreatePort(0,0)))
{
goto endser;
}
if(!(QuerySER->IOSer.io_Message.mn_ReplyPort=(struct MsgPort *)CreatePort(0,0)))
{
goto endser;
}
/* Open Timer.device */
if(Timer_Port=(struct MsgPort *)CreatePort(0,0))
{
if((Timer=(struct timerequest *)CreateExtIO(Timer_Port,sizeof(*Timer))))
{
if(!(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)Timer,0L)))
{
Timer->tr_node.io_Command =TR_ADDREQUEST;
Timer->tr_node.io_Flags =0;
Timer->tr_node.io_Error =0;
set_read(); /* start reading immediately */
return 1;
}
}
}
Timer->tr_node.io_Device=NULL;
close_timer();
endser:
close_ser();
return 0;
}
void close_ser()
{
if(auxbuf)
{
FreeMem(auxbuf,AUXBUFSIZE);
auxbuf=NULL;
}
if(ReadSER)
{
if(ReadSER->IOSer.io_Device)
CloseDevice((struct IORequest *)ReadSER);
if(ReadSER->IOSer.io_Message.mn_ReplyPort)
DeletePort(ReadSER->IOSer.io_Message.mn_ReplyPort);
FreeMem(ReadSER,sizeof(*ReadSER));
ReadSER=NULL;
}
if(WriteSER)
{
if(WriteSER->IOSer.io_Message.mn_ReplyPort)
DeletePort(WriteSER->IOSer.io_Message.mn_ReplyPort);
FreeMem(WriteSER,sizeof(*WriteSER));
WriteSER=NULL;
}
if(QuerySER)
{
if(QuerySER->IOSer.io_Message.mn_ReplyPort)
DeletePort(QuerySER->IOSer.io_Message.mn_ReplyPort);
FreeMem(QuerySER,sizeof(*QuerySER));
QuerySER=NULL;
}
SerialSpeed=-1;
}
void close_timer()
{
if(Timer)
{
if(Timer->tr_node.io_Device)
CloseDevice((struct IORequest *)Timer);
DeleteExtIO((struct IORequest *)Timer);
}
if(Timer_Port)
DeletePort(Timer_Port);
}
void chk_file(char *name)
{ register char *s=name;
strcpy(device,SERIALNAME); /* set the defaults */
unitnum=0;
aux_stat=AUX_CRLF;
serflags=SERF_7WIRE | SERF_RAD_BOOGIE | SERF_XDISABLED;
checkcd=0;
SerialSpeed=-1;
Mode=MODE_RAW;
if(!*s)
return; /* no params */
while(*s && *s!='/')
s++;
if(!*s)
{
strcpy(device,name);
return; /* no unit number */
}
unitnum=atoi(s+1);
strncpy(device,name,(long)(s-name));
device[(long)(s-name)]='\0';
s++;
while(1)
{
while(*s && *s!='/')
s++;
if(!*s)
break;
++s;
if(!strncmp(s,"raw",3))
{ aux_stat&=~AUX_ECHO;
Mode=MODE_RAW;
s+=3;
}
else
if(!strncmp(s,"con",3))
{ aux_stat|=AUX_ECHO;
Mode=MODE_CONSOLE;
s+=3;
}
else
if(!strncmp(s,"shared",6))
{ serflags|=SERF_SHARED;
s+=6;
}
else
if(!strncmp(s,"exclusive",9))
{ serflags&=~SERF_SHARED;
s+=9;
}
else
if(!strncmp(s,"noflow",6))
{ serflags&=~SERF_7WIRE;
s+=6;
}
else
if(!strncmp(s,"7wire",5))
{ serflags|=SERF_7WIRE;
s+=5;
}
else
if(!strncmp(s,"checkcd",7))
{ checkcd=-1;
s+=7;
}
else
if(!strncmp(s,"speed",5))
{
SerialSpeed=atol(s+=5);
}
}
}
/*
* misc.c - support routines - Phillip Lindsay (C) Commodore 1986
* You may freely distribute this source and use it for Amiga Development -
* as long as the Copyright notice is left intact.
*
* 30-SEP-86
*
*/
/* returnpkt() - packet support routine
* here is the guy who sends the packet back to the sender...
*/
void returnpkt(struct DosPacket *packet,struct Process *myproc,ULONG res1,ULONG res2)
{ register struct Message *mess=packet->dp_Link;
register struct MsgPort *replyport=packet->dp_Port;
packet->dp_Res1 =res1;
packet->dp_Res2 =res2;
packet->dp_Port =&myproc->pr_MsgPort;
mess->mn_Node.ln_Name=(char *) packet;
mess->mn_Node.ln_Succ=mess->mn_Node.ln_Pred=NULL;
PutMsg(replyport, mess);
}
/*
* taskwait() ... Waits for a message to arrive at your port and
* extracts the packet address which is returned to you.
*/
struct DosPacket *taskwait(struct Process *myproc)
{ register struct MsgPort *myport=&myproc->pr_MsgPort;
register struct Message *mymess;
WaitPort(myport);
mymess=(struct Message *)GetMsg(myport);
return((struct DosPacket *)mymess->mn_Node.ln_Name);
}
/* end of misc.c */